#include "sound_pool.bgt"
string wrapf;
string openf;
int enabless=0;
int menuclicks;
int menuedges;
int clickedge=0;
int enableit=0;
int enablelr=0;
int enableud=0;
int voltime=50;
int nsnums;
double menuvol;
timer voltimer;
sound menumus;
sound_pool spool;
string menuclick;
string menuedge;
string esf, escf;
int esp, esv, esn, escp, escn, escv;
tts_voice tts;
int found_reader=0;
double item_count, menu_position;


void menuclicknsstudios123() {
if (enabless==1)
menuclicks=spool.play_stationary_extended(menuclick, false, 0, (menu_position*100/item_count)-50, 0, 100, false);
else
menuclicks=spool.play_stationary(menuclick, false, false);
}
void menuedgensstudios123() {
if (enabless==1)
spool.play_stationary_extended(menuedge, false, 0, (menu_position*100/item_count)-50, 0, 100, false);
else
spool.play_stationary(menuedge, false, false);
}bool speak(string text, bool interrupt=true)
{
if(found_reader==0)
found_reader=auto_select_screen_reader();
if(found_reader==0)
{

// We cannot find a running screen reader, so we use a global tts_voice object.
if(interrupt)
tts.speak_interrupt(text);
else
tts.speak(text);
}

if(interrupt)
screen_reader_speak_interrupt(found_reader, text);
else
screen_reader_speak(found_reader, text);
return true;
}

int auto_select_screen_reader()
{
for(int i=1;i<=4;i++)
{
if(screen_reader_is_running(i)==false)
continue;
return i;
}
return 0;
}
void fade (sound@ handle, double final_volume=-50, double delay=25)
{
if (handle.volume == final_volume)
{
return;
}
while (handle.volume != final_volume)
{
if (handle.volume > final_volume)
{
handle.volume=handle.volume-1;
}
else if (handle.volume < final_volume)
{
handle.volume=handle.volume+1;
}
wait (delay);
}
}
class dynamic_menu_item
{
string option;
bool is_filename;

dynamic_menu_item()
{
option="";
is_filename=true;
}
}


class dynamic_menu
{
bool edge_added=false;
bool wrap;
bool allow_escape;

dynamic_menu()
{
running=false;
reset(true);
}
void enable_side_scrolling(bool ss)
{
if (ss==true)
{
enabless=1;
}
if (ss==false)
{
enabless=0;
}
}
void enable_numbers(bool choice=false) {
if (choice)
nsnums=1;
else
nsnums=0;
}
void enable_left_and_right(bool enablel)
{
if (enablel==true)
{
enablelr=1;
}
if (enablel==false)
{
enablelr=0;
}
}
void enable_up_and_down(bool enableu)
{
if (enableu==true)
{
enableud=1;
}
if (enableu==false)
{
enableud=0;
}
}
void click_at_edge(bool bclickedge)
{
if (bclickedge==true)
{
clickedge=1;
}
if (bclickedge==false)
{
clickedge=0;
}
}
void repeat_last_item_at_bottom(bool enablei)
{
if (enablei==true)
{
enableit=1;
}
if (enablei==false)
{
enableit=0;
}
}
void add_click_sound(string cfilename) {
menuclick=cfilename;
}
void add_enter_sound(string filename, int enterpan=0, int enterpitch=100, int entervolume=0) {
esf=filename;
esp=enterpitch;
esn=enterpan;
esv=entervolume;
}
void add_escape_sound(string filename) {
escf=filename;
}
void add_edge_sound(string efilename) {
edge_added=true;
menuedge=efilename;
}
void add_open_sound(string filename) {
openf=filename;
}
void add_wrap_sound(string filename) {
wrapf=filename;
}
void stopmusic()
{
menumus.stop();
}
void play_music()
{
menumus.play();
}
void fade_music(int value1)
{
fade(menumus,-50,value1);
menumus.stop();
}
void add_music(string filename, int muspan=0, int muspitch=100) {
menumus.pan=muspan;
menumus.pitch=muspitch;
menumus.stream(filename);
}
bool add_item(string filename)
{
if(running==true)
{
return false;
}
double new_index=item_list.length();
item_list.resize(new_index+1);
item_list[new_index].option=filename;
item_list[new_index].is_filename=true;
return true;
}

bool add_item_tts(string text)
{
if(running==true)
{
return false;
}
double new_index=item_list.length();
item_list.resize(new_index+1);
item_list[new_index].option=text;
item_list[new_index].is_filename=false;
return true;
}

double get_item_count()
{
return item_list.length();
}

bool set_tts_object(tts_voice@ handle)
{
if(running==true)
{
return false;
}
@tts_handle=@handle;
return true;
}

bool set_callback(menu_callback@ callback, string user_data)
{


if(running==true)
{
return false;
}
@callback_handle=@callback;
callback_data=user_data;
return true;
}

double run(string intro, bool is_intro_tts)
{
return run_extended(intro, is_intro_tts, 0, false);
}

double run_extended(string intro, bool is_intro_tts, double start_position, bool auto_speak_first)
{
if(running==true)
{
return -1;
}
item_count=item_list.length();
if(item_count==0)
{
return -1;
}
if(start_position>item_count)
{
return -1;
}
menu_position=start_position;
bool speak_item=false;
bool initial=auto_speak_first;
sound menu_sound;
bool reset_tts=false;
if(@tts_handle==null)
{
tts_voice temp_voice;
@tts_handle=temp_voice;
reset_tts=true;
}
if(intro!="")
{
if(is_intro_tts==true)
{
if(speak(intro, true)==false)
{
if(reset_tts==true)
@tts_handle=null;
return -1;
}
}
else
{
if(menu_sound.stream(intro)==false)
{
if(reset_tts==true)
@tts_handle=null;
return -1;
}
menu_sound.play();
}
}
spool.play_stationary(openf, false);
menumus.play_looped();
running=true;
while(true)
{

if(speak_item==true)
{
if(item_list[menu_position-1].is_filename==true)
{
if(menu_sound.stream(item_list[menu_position-1].option)==false)
{
if(reset_tts==true)
@tts_handle=null;
running=false;
return -1;
}
menu_sound.play();
}
else
{
if(menu_sound.active==true)
{
menu_sound.close();
}
if(speak(item_list[menu_position-1].option)==false)
{
if(reset_tts==true)
@tts_handle=null;
running=false;
return -1;
}
}
speak_item=false;
}
if(initial==true)
{
if(item_list[menu_position-1].is_filename==true)
{
if(menu_sound.playing==false)
{
speak_item=true;
initial=false;
continue;
}
}
else
{
if(tts_handle.speaking==false)
{
speak_item=true;
initial=false;
continue;
}
}
}
if (nsnums==1) {
if (key_up(KEY_RSHIFT) and key_pressed(KEY_1) and get_item_count()>=1) {
menu_position=1;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_up(KEY_RSHIFT) and key_pressed(KEY_2) and get_item_count()>=2) {
menu_position=2;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_up(KEY_RSHIFT) and key_pressed(KEY_3) and get_item_count()>=3) {
menu_position=3;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_up(KEY_RSHIFT) and key_pressed(KEY_4) and get_item_count()>=4) {
menu_position=4;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_up(KEY_RSHIFT) and key_pressed(KEY_5) and get_item_count()>=5) {
menu_position=5;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_up(KEY_RSHIFT) and key_pressed(KEY_6) and get_item_count()>=6) {
menu_position=6;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_up(KEY_RSHIFT) and key_pressed(KEY_7) and get_item_count()>=7) {
menu_position=7;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_up(KEY_RSHIFT) and key_pressed(KEY_8) and get_item_count()>=8) {
menu_position=8;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_up(KEY_RSHIFT) and key_pressed(KEY_9) and get_item_count()>=9) {
menu_position=9;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_up(KEY_RSHIFT) and key_pressed(KEY_0) and get_item_count()>=10) {
menu_position=10;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_up(KEY_RSHIFT) and key_pressed(KEY_MINUS) and get_item_count()>=11) {
menu_position=11;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_up(KEY_RSHIFT) and key_pressed(KEY_EQUALS) and get_item_count()>=12) {
menu_position=12;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_up(KEY_RSHIFT) and key_pressed(KEY_BACK) and get_item_count()>=13) {
menu_position=13;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_down(KEY_RSHIFT) and key_pressed(KEY_1) and get_item_count()>=14) {
menu_position=14;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_down(KEY_RSHIFT) and key_pressed(KEY_2) and get_item_count()>=15) {
menu_position=15;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_down(KEY_RSHIFT) and key_pressed(KEY_3) and get_item_count()>=16) {
menu_position=16;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_down(KEY_RSHIFT) and key_pressed(KEY_4) and get_item_count()>=17) {
menu_position=17;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_down(KEY_RSHIFT) and key_pressed(KEY_5) and get_item_count()>=18) {
menu_position=18;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_down(KEY_RSHIFT) and key_pressed(KEY_6) and get_item_count()>=19) {
menu_position=19;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_down(KEY_RSHIFT) and key_pressed(KEY_7) and get_item_count()>=20) {
menu_position=20;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_down(KEY_RSHIFT) and key_pressed(KEY_8) and get_item_count()>=21) {
menu_position=21;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_down(KEY_RSHIFT) and key_pressed(KEY_9) and get_item_count()>=22) {
menu_position=22;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_down(KEY_RSHIFT) and key_pressed(KEY_0) and get_item_count()>=23) {
menu_position=23;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_down(KEY_RSHIFT) and key_pressed(KEY_MINUS) and get_item_count()>=24) {
menu_position=24;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_down(KEY_RSHIFT) and key_pressed(KEY_EQUALS) and get_item_count()>=25) {
menu_position=25;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
else if (key_down(KEY_RSHIFT) and key_pressed(KEY_BACK) and get_item_count()>=26) {
menu_position=26;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
}


if(key_pressed(KEY_RETURN) or key_pressed(KEY_SPACE))
{
if(menu_position!=0)
{
if (enabless==1)
{
esn=(menu_position*100/item_count)-50;
}
spool.play_stationary_extended(esf, false, 0, esn, esv, esp, false);
running=false;
return menu_position;
}
}
if(allow_escape==true)
{
if(key_pressed(KEY_ESCAPE))
{
if (enabless==1)
{
escn=(menu_position*100/item_count)-50;
}
spool.play_stationary(escf, false);
running=false;
return 0;
}
}
if(key_pressed(KEY_UP) and enableud==1)
{
initial=false;
if(menu_position==0)
{
menu_position=item_count;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
if(menu_position==1)
{
if(wrap==true)
{
menu_position=item_count;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
spool.play_stationary(wrapf, false);
speak_item=true;
continue;
}
else
{
if (edge_added==true)
{
if (clickedge==1)
{
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
}
menuedges=spool.play_stationary(menuedge, false, false);
if (enabless==1)
{
spool.items[menuedges].handle.pan=(menu_position*100/item_count)-50;
}
if (enableit==1)
{
speak_item=true;
}
continue;
}
if (edge_added==false)
{
if (enableit==1)
{
speak_item=true;
}
continue;
}
}
}
menu_position-=1;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
if(key_pressed(KEY_LEFT) and enablelr==1)
{
initial=false;
if(menu_position==0)
{
menu_position=item_count;
menuclicknsstudios123();
speak_item=true;
continue;
}
if(menu_position==1)
{
if(wrap==true)
{
menu_position=item_count;
menuclicknsstudios123();
spool.play_stationary(wrapf, false);
speak_item=true;
continue;
}
else
{
if (edge_added==true)
{
if (clickedge==1)
{
menuclicknsstudios123();
}
menuedgensstudios123();
if (enableit==1)
{
speak_item=true;
}
continue;
}
if (edge_added==false)
{
if (enableit==1)
{
speak_item=true;
}
continue;
}
}
}
menu_position-=1;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
if(key_pressed(KEY_DOWN) and enableud==1)
{
initial=false;
if(menu_position==item_count)
{
if(wrap==true)
{
menu_position=1;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
spool.play_stationary(wrapf, false);
speak_item=true;
continue;
}
else
{
if (edge_added==true)
{
if (clickedge==1)
{
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
}
menuedges=spool.play_stationary(menuedge, false, false);
if (enabless==1)
{
spool.items[menuedges].handle.pan=(menu_position*100/item_count)-50;
}
if (enableit==1)
{
speak_item=true;
}
continue;
}
if (edge_added==false)
{
if (enableit==1)
{
speak_item=true;
}
continue;
}
}
}
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
menu_position+=1;
speak_item=true;
continue;
}
if(key_pressed(KEY_RIGHT) and enablelr==1)
{
initial=false;
if(menu_position==item_count)
{
if(wrap==true)
{
menu_position=1;
menuclicknsstudios123();
spool.play_stationary(wrapf, false);
speak_item=true;
continue;
}
else
{
if (edge_added==true)
{
if (clickedge==1)
{
menuclicknsstudios123();
}
menuedgensstudios123();
if (enableit==1)
{
speak_item=true;
}
continue;
}
if (edge_added==false)
{
if (enableit==1)
{
speak_item=true;
}
continue;
}
}
}
menu_position+=1;
menuclicks=spool.play_stationary(menuclick, false, false);
if (enabless==1)
{
spool.items[menuclicks].handle.pan=(menu_position*100/item_count)-50;
}
speak_item=true;
continue;
}
if (key_down(KEY_NEXT) and voltimer.elapsed>=voltime)
{
menumus.volume=menumus.volume-2;
voltimer.restart();
}
if (key_down(KEY_PRIOR) and voltimer.elapsed>=voltime)
{
menumus.volume=menumus.volume+2;
voltimer.restart();
}
if (key_pressed(KEY_END))
{
menumus.volume=-50;
}
if (key_pressed(KEY_HOME))
{
menumus.volume=0;
}
if(@callback_handle!=null)
{
int callback_result=callback_handle(this, callback_data);
if(callback_result!=0)
{
if(reset_tts==true)
@tts_handle=null;
running=false;
return callback_result;
}
}
wait(5);
}
if(reset_tts==true)
@tts_handle=null;
running=false;
return -1;
}

bool reset(bool completely)
{
if(running==true)
{
return false;
}
item_list.resize(0);
if(completely==true)
{
wrap=true;
allow_escape=true;
@tts_handle=null;
}
return true;
}



tts_voice@ tts_handle;
menu_callback@ callback_handle;
string callback_data;
bool running;
dynamic_menu_item[] item_list;
}

funcdef int menu_callback(dynamic_menu@, string);